package chat

import (
	"bufio"
	"encoding/json"
	"io"
	"log"
	"math/rand"
	"net/http"
	"os"
	"reflect"
	"strconv"
	"time"

	"github.com/gorilla/websocket"
	"github.com/sirupsen/logrus"
)

const (
	// Time allowed to write a message to the peer.
	writeWait = 10 * time.Second

	// Time allowed to read the next pong message from the peer.
	pongWait = 60 * time.Second

	// Send pings to peer with this period. Must be less than pongWait.
	pingPeriod = (pongWait * 9) / 10

	// Maximum message size allowed from peer.
	maxMessageSize = 512

	handshakeWait = 60 * time.Second
)

var AIChatTimes = 0

var upgrader = websocket.Upgrader{
	// 解决跨域问题
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

func process(conn *websocket.Conn) {
	defer conn.Close()

	for {
		log.Println("websocket loop start ===============>")
		loop := 0
		// conn.SetPongHandler(func(appData string) error {
		// 	println("pong handler")
		// 	conn.WriteMessage(websocket.PongMessage, []byte("pong"))
		// 	return conn.SetReadDeadline(time.Now().Add(handshakeWait))
		// })

		// conn.SetPingHandler(func(appData string) error {
		// 	println("ping handler")
		// 	conn.WriteMessage(websocket.PingMessage, []byte("ping"))
		// 	return conn.SetReadDeadline(time.Now().Add(handshakeWait))
		// })
		for {
			// 假设我们有一个消息要发送给客户端
			// message := []byte("Hello, client! times " + strconv.Itoa(loop))
			// 向客户端发送消息
			// err = conn.WriteMessage(websocket.TextMessage, message)
			// if err != nil {
			// 	log.Println("Error sending message to client:", err)
			// 	return
			// }

			loop += 1
			// 接收发送消息 方式一
			{
				// 读客户端发送的消息 这个会阻塞当前程序
				messageType, message, err := conn.ReadMessage()
				if err != nil {
					log.Println("Error during message reading:", err)
					return
				}
				// log.Printf("Server Received: %s", message)

				msgBody := map[string]interface{}{}
				jsonErr := json.Unmarshal(message, &msgBody)
				if jsonErr != nil {
					// log.Println("JSON unmarlshal:", err)
				} else {
					eventName := reflect.ValueOf(msgBody["eventName"]).Interface().(string)
					log.Println("chat message event  ", eventName)
					if eventName == "AiChat" {
						sendAIChatMsg(conn)
					} else if eventName == "voltageChart" {
						sendVoltageChart(conn)
					} else {
						data := reflect.ValueOf(msgBody["data"]).Interface().(map[string]interface{})
						if data["msg"] == "确认" {
							return
						}
					}
					write(conn, message)
				}
				// 给客户端发送消息
				err = conn.WriteMessage(messageType, message)
				if err != nil {
					log.Println("Error during message writing:", err)
					return
				}
			}

			// // 接收发送消息 方式二
			// {
			// 	messageType, r, err := conn.NextReader()
			// 	if err != nil {
			// 		return
			// 	}

			// 	w, err := conn.NextWriter(messageType)
			// 	if err != nil {
			// 		return
			// 	}

			// 	if _, err := io.Copy(w, r); err != nil {
			// 		return
			// 	}
			// 	if err := w.Close(); err != nil {
			// 		return
			// 	}
			// }
		}
	}
}

func write(conn *websocket.Conn, msg []byte) {
	defer conn.Close()

	ticker := time.NewTicker(5 * time.Second)
	defer ticker.Stop() // 在不再需要时停止Ticker
	for range ticker.C {
		// 在这里执行你的定时任务
		// 假设我们有一个消息要发送给客户端
		_ = conn.WriteMessage(websocket.TextMessage, msg)
	}
}

func sendVoltageChart(conn *websocket.Conn) {
	defer conn.Close()

	ticker := time.NewTicker(5 * time.Second)
	defer ticker.Stop()
	cout := 1
	for range ticker.C {
		num := cout
		cout += 1
		voltages := make([]interface{}, 1000)
		for i := 0; i < 1000; i++ {
			data := map[string]interface{}{
				"value": (rand.Float64() + 5) * 10,
				"date":  strconv.Itoa(num) + "-" + strconv.Itoa(i),
			}
			voltages[i] = data
		}

		currents := make([]interface{}, 1000)
		for i := 0; i < 1000; i++ {
			data := map[string]interface{}{
				"value": (rand.Float64() + 5) * 100,
				"date":  strconv.Itoa(num) + "-" + strconv.Itoa(i),
			}
			currents[i] = data
		}

		data := map[string]interface{}{
			"voltage": voltages,
			"current": currents,
		}
		message := map[string]interface{}{
			"eventName": "HighFrequencyData",
			"data":      data,
		}
		msg, err := json.Marshal(message)
		if err == nil {
			// 向客户端发送消息
			err = conn.WriteMessage(websocket.TextMessage, msg)
			if err != nil {
				log.Println("Error sending message to client:", err)
				break
			}
		}

	}

}

func sendMessage(conn *websocket.Conn) {
	defer conn.Close()

	ticker := time.NewTicker(5 * time.Second)
	defer ticker.Stop() // 在不再需要时停止Ticker

	for t := range ticker.C {
		// 在这里执行你的定时任务
		// 假设我们有一个消息要发送给客户端
		message := map[string]interface{}{
			"eventName": "showAlarm",
			"data": map[string]interface{}{
				"info": "hello",
				"id":   "id",
				"num":  t,
			},
		}

		msg, err := json.Marshal(message)
		if err == nil {
			// 向客户端发送消息
			err = conn.WriteMessage(websocket.TextMessage, msg)
			if err != nil {
				log.Println("Error sending message to client:", err)
				break
			}
		}
	}
}

func sendAIChatMsg(conn *websocket.Conn) {
	defer conn.Close()

ReSend:
	chatFiles := ""
	switch AIChatTimes {
	case 0:
		chatFiles = "webserver/assets/bot/chat/chat_times0.json"
	case 1:
		chatFiles = "webserver/assets/bot/chat/chat_times1.json"
	case 2:
		chatFiles = "webserver/assets/bot/chat/chat_times2.json"
	case 3:
		chatFiles = "webserver/assets/bot/chat/chat_times3.json"
	default:
		chatFiles = "webserver/assets/bot/chat/chat_times0.json"
	}

	inputReader, error := os.Open(chatFiles)
	if error != nil {
		logrus.Error(error)
	} else {
		inputReader := bufio.NewReader(inputReader)
		var data []byte
		var buffer [512]byte // 用于存储每次读取的数据块

		for {
			n, err := inputReader.Read(buffer[:])
			if err != nil {
				if err == io.EOF {
					break // 读取完毕
				}
				logrus.Error("Error reading from buffer:", err)
				return
			}
			data = append(data, buffer[:n]...) // 将读取的数据块添加到data切片中
		}

		logrus.Debug("message  data: ", string(data))
		conn.WriteMessage(websocket.TextMessage, data)
		if AIChatTimes == 2 {
			AIChatTimes += 1
			goto ReSend
		}
	}

	AIChatTimes += 1
	if AIChatTimes > 3 {
		AIChatTimes = 0
	}
}

func sendEventMsg(conn *websocket.Conn, eventName string, data map[string]interface{}) {
	defer conn.Close()
	message := map[string]interface{}{
		"eventName": eventName,
		"data":      data,
	}

	msg, err := json.Marshal(message)
	if err == nil {
		// 向客户端发送消息
		err = conn.WriteMessage(websocket.TextMessage, msg)
		if err != nil {
			log.Println("Error sending message to client:", err)
		}
	}
}

func WebSocketHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("====socket start ========")
	// Upgrade our raw HTTP connection to a websocket based one
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Print("Error during connection upgradation:", err)
		return
	}
	go process(conn)
	// go sendMessage(conn)
}

func WebSocketAIHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("====ai socket start ========")
	// Upgrade our raw HTTP connection to a websocket based one
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Print("Error during connection upgradation:", err)
		return
	}
	go process(conn)
	// go sendMessage(conn)
}

func ConfigWebSocketHandler() {
	http.Handle("/socket", http.HandlerFunc(WebSocketAIHandler))
}

// 这个应该是aichat 的
func ConfigAIChatHandler() {
	http.Handle("/openai", http.HandlerFunc(WebSocketHandler))
}

func ConfigWebSrocketWithMux(mux *http.ServeMux) {
	mux.Handle("/socket", http.HandlerFunc(WebSocketAIHandler))
}

func ConfigAIChatWithMux(mux *http.ServeMux) {
	mux.Handle("/chat", http.HandlerFunc(WebSocketHandler))
}
